package http

import (
	"fmt"
	"giot/pkg/logger"
	"io"
	"net/http"
	"net/url"
	"strings"
	"time"
)

type Deal struct {
}

const defaultTimeOut = 5

// Post 方法
// 参数:
//
//	url		:post 地址
//	data	:post数据,放在body中
//	header	:header头
func (hs *Deal) Post(url, data string, header map[string]string) (*http.Response, error) {
	snReader := strings.NewReader(data)
	return hs.doPost(url, data, header, snReader)
}

func (hs *Deal) PostUrlEncoded(urlPath string, urlData map[string]string, header map[string]string) (*http.Response, error) {
	values := url.Values{}
	data := ""
	if urlData != nil && len(urlData) > 0 {
		for k, v := range urlData {
			values.Add(k, v)
			data = fmt.Sprintf("&&%v=%v", k, v)
		}
	}
	reader := strings.NewReader(values.Encode())
	return hs.doPost(urlPath, data, header, reader)
}

func (hs *Deal) Get(url string, header map[string]string) (*http.Response, error) {
	return hs.doGet(url, header, nil)
}

func (hs *Deal) doGet(url string, header map[string]string, reader io.Reader) (*http.Response, error) {
	return hs.doRequest(http.MethodGet, url, "", defaultTimeOut, header, reader)
}

func (hs *Deal) doPost(url, data string, header map[string]string, reader io.Reader) (*http.Response, error) {
	return hs.doRequest(http.MethodPost, url, data, defaultTimeOut, header, reader)
}

func (hs *Deal) doRequest(method, url string, data string, t int, header map[string]string, reader io.Reader) (*http.Response, error) {
	request, err2 := http.NewRequest(method, url, reader)
	if nil != err2 {
		err := fmt.Errorf("创建请求发生错误,%v", err2)
		return nil, err
	}
	if t < 0 {
		t = defaultTimeOut
	}
	httpClient := &http.Client{
		Timeout: time.Duration(t) * time.Second,
	}
	if len(header) > 0 {
		for k, v := range header {
			if request.Header.Get(k) != "" {
				request.Header.Del(k)
			}
			request.Header.Add(k, v)
		}
	}
	resp, err := httpClient.Do(request)

	if err != nil || nil == resp {
		var err1 error
		if nil != resp {
			err1 = fmt.Errorf("向[%v]请求[%v]失败,错误:[%v]", url, data, err)
		} else {
			err1 = fmt.Errorf("向[%v]请求[%v]失败,错误:[%v]", url, data, err)
		}
		return nil, err1
	}

	if resp.StatusCode != 200 {
		err = fmt.Errorf("向[%v]请求[%v]失败,错误:[%v]", url, data,
			fmt.Sprintf("http的[%v]响应:%v,%d", method, resp.Status, resp.StatusCode))
		return resp, err
	}
	logger.Infof("向[%v]请求[%v]成功", url, data)
	return resp, nil
}
